const schedule = require("node-schedule");
const lodash = require("lodash");
const moment = require("moment");
const Raven = require("raven");
const Doodoo = require("doodoo.js");
const context = require("./context");
const Code = require("./lib/wxa/code.class");

const app = new Doodoo();
app.core();
// app.plugin("dingding", {
//     url:
//         "xxx"
// });
// doodoo.hook.run("dingding", "系统提示", "计划任务启动成功");

if (process.env.NODE_ENV === "docker") {
    Raven.config(
        "http://f9fdd721b4c44797ba703ece39c96904@sentry.oneqing.com/2",
        {
            release: "20180808"
        }
    ).install();
    app.on("error", err => {
        Raven.captureException(err, (err, eventId) => {
            console.log("Reported error " + eventId);
        });
    });
}

async function checkWxaAuthorizerAccessToken(wxa) {
    if (new Date().getTime() >= wxa.expires_at) {
        const code = new Code(
            process.env.OPEN_APPID,
            process.env.OPEN_APPSECRET
        );
        const refreshAuthToken = await code.refreshAuthToken(
            wxa.authorizer_appid,
            wxa.authorizer_refresh_token
        );
        if (refreshAuthToken.errmsg) {
            console.error(refreshAuthToken);
            return;
        }

        const data = {
            expires_at:
                new Date().getTime() +
                (refreshAuthToken.expires_in - 100) * 1000,
            authorizer_access_token: refreshAuthToken.authorizer_access_token,
            authorizer_refresh_token: refreshAuthToken.authorizer_refresh_token
        };
        return await doodoo.models.wxa.forge(Object.assign(wxa, data)).save();
    }
    return wxa;
}

async function autoUpdateWxa() {
    // 自动更新小程序
    const today = moment().format("YYYYMMDD");
    console.log(`Start wxa update -- ${today}`);

    const code = new Code(process.env.OPEN_APPID, process.env.OPEN_APPSECRET);
    const wxaAudits = await doodoo.models.wxa_audit.query({}).fetchAll({
        withRelated: ["wxa", "template_wxa"]
    });

    for (const wxaAudit of wxaAudits) {
        if (wxaAudit.templateid !== wxaAudit.template_wxa.templateid) {
            if (!wxaAudit.wxa.authorized || !wxaAudit.wxa.status) {
                continue;
            }

            console.log(
                `Update wxa ${wxaAudit.wxa.nick_name} ${
                    wxaAudit.wxa.authorizer_appid
                }`
            );

            const wxa = await checkWxaAuthorizerAccessToken(wxaAudit.wxa);
            if (!wxa || !wxa.authorizer_access_token) {
                continue;
            }

            const audit_items = JSON.parse(wxaAudit.audit_item);
            const _wxaAudit = {
                template_wxa_id: wxaAudit.template_wxa_id,
                templateid: wxaAudit.template_wxa.templateid,
                ext_json: JSON.stringify(
                    lodash.merge(
                        {
                            window: {
                                navigationBarTitleText: wxaAudit.wxa.nick_name
                            }
                        },
                        {
                            ext: Object.assign({
                                envVersion: "release",
                                appid: wxaAudit.wxa.authorizer_appid
                            })
                        },
                        JSON.parse(wxaAudit.template_wxa.ext_json || "{}")
                    )
                ),
                user_version: today,
                user_desc: wxaAudit.user_desc || "小程序平台"
            };
            const commit = await code.commit(
                wxa.authorizer_access_token,
                _wxaAudit.templateid,
                _wxaAudit.ext_json,
                _wxaAudit.user_version,
                _wxaAudit.user_desc
            );
            if (commit.errmsg !== "ok") {
                console.error(context.wxaErr(commit));
                continue;
            }

            const audit = await code.submit_audit(
                wxa.authorizer_access_token,
                audit_items
            );
            if (audit.errmsg === "ok") {
                await doodoo.models.wxa_audit
                    .forge({
                        id: wxaAudit.id,
                        wxa_id: wxa.id,
                        template_wxa_id: _wxaAudit.template_wxa_id,
                        templateid: _wxaAudit.templateid,
                        auditid: audit.auditid,
                        audit_item: JSON.stringify(audit_items),
                        ext_json: _wxaAudit.ext_json,
                        user_version: _wxaAudit.user_version,
                        user_desc: _wxaAudit.user_desc,
                        release: 0
                    })
                    .save();
            } else {
                console.error(context.wxaErr(audit));
                continue;
            }
        }
    }

    console.log(`End wxa update -- ${today}`);
}

async function autoUpdateFree() {
    const templates = await doodoo.models.template.query({}).fetchAll();
    for (const template of templates) {
        await doodoo.redis.setAsync(
            `template:free:${template.id}`,
            template.free,
            "EX",
            3600 * 24
        );
    }
}

async function autoCleanFree() {
    const keys = await doodoo.redis.keysAsync(
        `${process.env.REDIS_PREFIX}template:free:*`
    );
    const length = `${process.env.REDIS_PREFIX}template:free:`.length;
    for (const key of keys) {
        await doodoo.redis.delAsync(`template:free:${key.substr(length)}`);
    }
}

// 发货7天后自动确认收货
const checkOrderSend = async () => {
    const data = moment()
        .subtract(7, "days")
        .format("YYYY-MM-DD HH:mm:ss");
    const nowdata = moment().format("YYYY-MM-DD HH:mm:ss");
    console.log("data-->", data, "nowdata-->", nowdata);
    await doodoo
        .model("order")
        .query(qb => {
            qb.where("status", "=", 1);
            qb.where("send_time", "<", data);
            qb.update({ status: 2, finsh_time: nowdata });
        })
        .fetchAll();
};
// 发货7天后不能退款
const checkOrderBack = async () => {
    const data = moment()
        .subtract(7, "days")
        .format("YYYY-MM-DD HH:mm:ss");
    // let nowdata = moment().format("YYYY-MM-DD HH:mm:ss");
    await doodoo
        .model("order")
        .query(qb => {
            qb.where("status", "=", 2);
            qb.where("finsh_status", "=", 0);
            qb.where("finsh_time", "<", data);
            qb.update({ finsh_status: 1 });
        })
        .fetchAll();
};

// 每天6:00自动更新小程序
schedule.scheduleJob("0 0 6 * * *", async () => {
    autoUpdateWxa();
});

// 每天10:00自动更新免费库存
schedule.scheduleJob("0 0 10 * * *", async () => {
    autoUpdateFree();
});

// 每天12:00自动清空免费库存
schedule.scheduleJob("0 0 12 * * *", async () => {
    autoCleanFree();
    await checkOrderSend();
    await checkOrderBack();
});


